//
// Created by Zxy on 2020/9/6.
//

#ifndef UNIONFIND_UNIONFIND5_H
#define UNIONFIND_UNIONFIND5_H
#include <cassert>
class UnionFind5 {
private:
    int *parent;
    int *rank;
    int count;
public:
    UnionFind5(int count){
        this->count = count;
        parent = new int[count];
        rank = new int[count];
        for(int i = 0; i < count; i++) {
            parent[i] = i;
            rank[i] = 1;
        }
    }
    ~UnionFind5(){
        delete [] parent;
        delete [] rank;
    }
    int find(int p){
        assert(p >= 0 && p < count);
        // 寻找根节点，复杂度O(n)
        while(p != parent[p]){
            parent[p] = parent[parent[p]];
            p = parent[p];
        }
        return p;
    }
    bool isConnected(int p, int q){
        return find(p) == find(q);
    }
    void unionElements(int p, int q){
        int pRoot = find(p);
        int qRoot = find(q);
        if(pRoot == qRoot) return;
        // 基于size优化
        if(rank[pRoot] < rank[qRoot]){
            // 不用维护层数
            parent[pRoot] = qRoot;
        }
        else if (rank[pRoot] > rank[qRoot]){
            // 不用维护层数
            parent[qRoot] = pRoot;
        }
        else{
            // rank[pRoot] == rank[qRoot]
            // 层数加1
            parent[pRoot] = qRoot;
            rank[qRoot]++;
        }
    }
};
#endif //UNIONFIND_UNIONFIND5_H
